grammar Calculator;

options{
output=AST;
ASTLabelType=CommonTree;
language=Java;
rewrite=true;
memoize=true;
backtrack=true;
}

program	
	:	statement+ 
	->	statement+	
	;

statement	
	:	ID EQ atom_expr SEMI -> ^(EQ ID atom_expr)
	|	ECHO atom_expr SEMI ->^(ECHO atom_expr)
	|	ECHO STR SEMI ->^(ECHO STR) 
	|	LOOP LPAREN ID EQ atom_expr SEMI comp_expr RPAREN statement+ ENDLP SEMI ->^(LOOP ID atom_expr comp_expr statement+)
	;

comp_expr
	:	a=atom_expr COMP b=atom_expr 
	->	^(COMP $a $b)
	; 
	
atom_expr
	:	LPAREN expr RPAREN 	->	expr 
	| 	atom			->	atom
	;
	
atom	
	:	NUM	->	NUM
	|	ID	->	ID
	;
	
expr	 
	:	add_expr 	-> add_expr
	| 	mul_expr 	-> mul_expr
	| 	sub_expr 	-> sub_expr 
	| 	div_expr	-> div_expr
	;

add_expr 
	:	ADD atom_expr+	
	->	^(ADD atom_expr+)
	;
 
mul_expr
	:	MUL atom_expr+	
	->	^(MUL atom_expr+)
	;
 
sub_expr
	:	SUB atom_expr atom_expr	
	->	^(SUB atom_expr atom_expr)
	;
	
div_expr
	:	DIV atom_expr atom_expr	
	->	^(DIV atom_expr atom_expr)
	;
	
STR	:	'\u0022' (options{greedy=false;}:.)* '\u0022';
COMP	:	'>' | '<' | '==' | '<=' | '>=';	
LOOP	:	'loop';
ENDLP	:	'end loop';
ECHO	:	'echo';
ID	:	('a'..'z'|'A'..'Z')+;
NUM	:	('0'..'9')+;
SEMI	:	';';
EQ	:	'=';
ADD	:	'+';
MUL	:	'*';
SUB	:	'-';
DIV	:	'/';	
LPAREN	:	'(';
RPAREN	:	')';
WS	:	(' '|'\t'|'\r'|'\n')+ {$channel=HIDDEN;};